/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.openatom.ubml.model.common.definition.cef.json.element;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.openatom.ubml.model.common.definition.cef.IGspCommonField;
import org.openatom.ubml.model.common.definition.cef.collection.GspFieldCollection;
import org.openatom.ubml.model.common.definition.cef.element.GspAssociation;
import org.openatom.ubml.model.common.definition.cef.entity.GspCommonField;
import org.openatom.ubml.model.common.definition.cef.entity.MappingRelation;
import org.openatom.ubml.model.common.definition.cef.json.CefNames;
import org.openatom.ubml.model.common.definition.cef.json.SerializerUtils;

/**
 * The Json Serializer Of CefField
 *
 * @ClassName: CefFieldSerializer
 * @Author: Benjamin Gong
 * @Date: 2021/1/11 17:13
 * @Version: V1.0
 */
public class CefFieldSerializer extends JsonSerializer<IGspCommonField> {
    @Override
    public void serialize(IGspCommonField field, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) {
        SerializerUtils.writeStartObject(jsonGenerator);
        writeBaseProperty(jsonGenerator, field);
        writeSelfProperty(jsonGenerator, field);
        SerializerUtils.writeEndObject(jsonGenerator);
    }

    //BaseProp
    public void writeBaseProperty(JsonGenerator writer, IGspCommonField value) {
        GspCommonField field = (GspCommonField)value;
        SerializerUtils.writePropertyValue(writer, CefNames.ID, field.getID());
        SerializerUtils.writePropertyValue(writer, CefNames.LABEL_ID, field.getLabelID());
        SerializerUtils.writePropertyValue(writer, CefNames.IS_REF, field.getIsRef());
        SerializerUtils.writePropertyValue(writer, CefNames.I18N_RESOURCE_INFO_PREFIX, field.getI18nResourceInfoPrefix());
        SerializerUtils.writePropertyValue(writer, CefNames.CUSTOMIZATION_INFO, field.getCustomizationInfo());
        writeAssociationCollection(writer, field);
        writeChildElements(writer, field.getChildElements());
        writeExtendFieldBaseProperty(writer, field);
    }

    /**
     * 序列化关联
     *
     * @param writer
     * @param info
     */
    private void writeAssociationCollection(JsonGenerator writer, IGspCommonField info) {
        SerializerUtils.writePropertyName(writer, CefNames.CHILD_ASSOCIATIONS);
        SerializerUtils.WriteStartArray(writer);
        if (info.getChildAssociations().size() > 0) {
            for (GspAssociation asso : info.getChildAssociations()) {
                this.getAssoConvertor().serialize(asso, writer, null);
            }

        }
        SerializerUtils.WriteEndArray(writer);
    }

    protected GspAssociationSerializer getAssoConvertor() {
        return new GspAssociationSerializer(this);
    }

    /**
     * 序列化ChildElement
     *
     * @param writer
     * @param collection
     */
    private void writeChildElements(JsonGenerator writer, GspFieldCollection collection) {
        if (collection == null || collection.size() <= 0)
            return;
        SerializerUtils.writePropertyName(writer, CefNames.CHILD_ELEMENTS);
        SerializerUtils.WriteStartArray(writer);
        for (IGspCommonField childField : collection)
            serialize(childField, writer, null);
        SerializerUtils.WriteEndArray(writer);
    }

    //抽象方法
    protected void writeExtendFieldBaseProperty(JsonGenerator writer, IGspCommonField field) {
    }



    //SelfProp
    public void writeSelfProperty(JsonGenerator writer, IGspCommonField value) {
        GspCommonField field = (GspCommonField)value;
        SerializerUtils.writePropertyValue(writer, CefNames.CODE, field.getCode());
        SerializerUtils.writePropertyValue(writer, CefNames.NAME, field.getName());
        SerializerUtils.writePropertyValue(writer, CefNames.OBJECT_TYPE, field.getObjectType().toString());
        SerializerUtils.writePropertyValue(writer, CefNames.MDATA_TYPE, field.getMDataType().toString());
        SerializerUtils.writePropertyValue(writer, CefNames.DEFAULT_VALUE, field.getDefaultValue());
        SerializerUtils.writePropertyValue(writer, CefNames.DEFAULT_VALUE_TYPE, field.getDefaultValueType().toString());
        SerializerUtils.writePropertyValue(writer, CefNames.LENGTH, field.getLength());
        SerializerUtils.writePropertyValue(writer, CefNames.PRECISION, field.getPrecision());
        SerializerUtils.writePropertyValue(writer, CefNames.IS_REQUIRE, field.getIsRequire());
        SerializerUtils.writePropertyValue(writer, CefNames.IS_MULTI_LANGUAGE, field.getIsMultiLanguage());
        SerializerUtils.writePropertyValue(writer, CefNames.IS_REF_ELEMENT, field.getIsRefElement());
        SerializerUtils.writePropertyValue(writer, CefNames.REF_ELEMENT_ID, field.getRefElementId());
        SerializerUtils.writePropertyValue(writer, CefNames.IS_UDT, field.getIsUdt());
        SerializerUtils.writePropertyValue(writer, CefNames.UDT_PKG_NAME, field.getUdtPkgName());
        SerializerUtils.writePropertyValue(writer, CefNames.ENABLE_RTRIM, field.isEnableRtrim());
        SerializerUtils.writePropertyValue(writer, CefNames.IS_BIG_NUMBER, field.isBigNumber());
        SerializerUtils.writePropertyValue(writer, CefNames.UDT_ID, field.getUdtID());
        SerializerUtils.writePropertyValue(writer, CefNames.UDT_NAME, field.getUdtName());
        SerializerUtils.writePropertyValue(writer, CefNames.IS_VIRTUAL, field.getIsVirtual());
        SerializerUtils.writePropertyValue(writer, CefNames.DYNAMIC_PROP_SET_INFO, field.getDynamicPropSetInfo());
        SerializerUtils.writePropertyValue(writer, CefNames.ENUM_INDEX_TYPE, field.getEnumIndexType());
        SerializerUtils.writePropertyValue(writer, CefNames.BE_LABEL, field.getBeLabel());
        SerializerUtils.writePropertyValue(writer, CefNames.BIZ_TAG_IDS, field.getBizTagIds());
        this.writeEnumValueList(writer, field);
        this.writeMappingRelation(writer, field.getMappingRelation());
        SerializerUtils.writePropertyValue(writer, CefNames.COLLECTION_TYPE, field.getCollectionType().toString());
        SerializerUtils.writePropertyValue(writer, CefNames.IS_FROM_ASSO_UDT, field.getIsFromAssoUdt());
        this.writeExtendFieldSelfProperty(writer, (IGspCommonField)field);
    }

    /**
     * 枚举信息序列化
     *
     * @param writer
     * @param field
     */
    private void writeEnumValueList(JsonGenerator writer, GspCommonField field) {
        SerializerUtils.writePropertyName(writer, CefNames.CONTAIN_ENUM_VALUES);
        SerializerUtils.WriteStartArray(writer);
        if (field.getContainEnumValues() != null && field.getContainEnumValues().size() > 0) {
            for (int index = 0; index < field.getContainEnumValues().size(); ++index)
                SerializerUtils.writePropertyValue_Object(writer, field.getContainEnumValues().get(index));
        }
        SerializerUtils.WriteEndArray(writer);
    }

    /**
     * MappingRelation序列化
     *
     * @param writer
     * @param mapping
     */
    private void writeMappingRelation(JsonGenerator writer, MappingRelation mapping) {
        if (mapping == null || mapping.getCount() <= 0)
            return;
        SerializerUtils.writePropertyName(writer, CefNames.MAPPING_RELATION);
        SerializerUtils.WriteStartArray(writer);
        for (String key : mapping.getKeys()) {
            SerializerUtils.writeStartObject(writer);
            SerializerUtils.writePropertyValue(writer, key, mapping.getMappingInfo(key));
            SerializerUtils.writeEndObject(writer);
        }
        SerializerUtils.WriteEndArray(writer);
    }

    //抽象方法
    protected void writeExtendFieldSelfProperty(JsonGenerator writer, IGspCommonField field) {
    }


}
